/**
 * Copyright (c) 2005-2012 springside.org.cn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package spring.data.jpa.repository.support;

import java.util.Collection;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.data.jpa.domain.Specification;

public class DynamicSpecifications {
    
    private DynamicSpecifications () {}

	/**
	 * 支持 and 和 or 条件,但仅支持想下面这样的条件: ...where C1.p1 and (C1.p2 or C1.p3)
	 * 
	 * @param filters
	 *            SearchFilter 数组 ,长度2,0 为and条件filter ,1 为 or条件filter
	 * @param clazz
	 * @return
	 */
	public static <T> Specification<T> bySearchFilter(final Collection<SearchFilter> andFilters, final Collection<SearchFilter> orFilters, final Class<T> clazz) {
		return new Specification<T>() {
            private static final long serialVersionUID = 1L;

            @Override
			public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				SpecificationImpl<T> specification = new SpecificationImpl<>(clazz);
				specification.setAndFilters(andFilters);
				specification.setOrFilters(orFilters);
				return specification.toPredicate(root, query, builder);
			}

		};
	}

	public static <T> Specification<T> bySearchDefinition(final JpaSearchSupport searchDefinition, final Class<T> clazz) {
		return new Specification<T>() {
		    
		    private static final long serialVersionUID = 1L;
			@Override
			public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				Collection<SearchFilter> andFilters = searchDefinition.getAndFilter();
				Collection<SearchFilter> orFilters = searchDefinition.getOrFilter();
				SpecificationImpl<T> specification = new SpecificationImpl<>(clazz);
				specification.setAndFilters(andFilters);
				specification.setOrFilters(orFilters);
				return specification.toPredicate(root, query, builder);
			}
		};
	}
}
